package linuxbox.reservation.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.sql.*;

import linuxbox.bean.*;
import linuxbox.common.*;
import linuxbox.reservation.logic.*;

public class BoxReservationAction extends Action
{
  BoxReservation home = BoxReservation.getInstance();
	protected static String listJSP = null;
	protected static String viewJSP = null;
	protected static String editJSP = null;
	private String strErrMsg = null;

  public void doAction(HttpSession aSession, BoxSession aBoxSession,
            HttpServletRequest req, HttpServletResponse resp) throws Exception
  {
    String str = req.getParameter("SubmitCancel");
    if ( str != null )
    {
      sendFile(listJSP,req,resp);
      return;
    }

    int curEntryID = 0;
    strErrMsg = null;
    str = req.getParameter("ID");
    if ( str != null)
    {
      curEntryID = Integer.parseInt(str);
    }

    if ( req.getParameter("SubmitSave") != null
      || req.getParameter("SubmitUpdate") != null )
    {
      //This functoin will forward to different jsp
      //depend on the result of the update
      saveToBean(curEntryID, req, resp, aBoxSession);
      return;
    }

    str = req.getParameter("SubmitDelete");
    if ( str != null )
    {
      deleteBean(curEntryID);
      sendFile(listJSP,req,resp);
      return;
    }

		Calendar currentDate = (Calendar)aSession.getAttribute("currentDate");
	  if ( currentDate == null )
		{
  		currentDate = Calendar.getInstance(aBoxSession.getTimeZone());
  		aSession.setAttribute("currentDate", currentDate);
  	}

		str = req.getParameter("t"); //time
		if ( str != null )
		{
			long tmp = Long.parseLong(str);
			currentDate.setTime(new java.sql.Date(tmp));
		}

    if ( req.getParameter("SubmitEdit") != null  )
    {
      // Now we'll go to the edit form
      BoxReservationEntry entry = null;
      if ( curEntryID == 0 )
      {
        setDefaultAttributes(req, aBoxSession);
      }
      else
      {
        entry = setBeanAttributes(req, aBoxSession, curEntryID);
      }
      if ( entry != null )
      {
        //TODO: check the user rights to see if can edit
        String curUserID = aBoxSession.getLoginID();
        if ( curUserID.compareTo(entry.getUserID()) == 0
        || false /* check rights */)
          sendFile(editJSP,req,resp);
        else
          sendFile(viewJSP,req,resp);
        return;
      }
      sendFile(editJSP,req,resp);
      return;
    }

    if ( req.getParameter("SubmitReEdit") != null  )
    {
  	  BoxReservationEntry entry = new BoxReservationEntry();
  	  BoxReservationRepeatEntry repeat = new BoxReservationRepeatEntry();
      getParameters(req, aBoxSession, entry, repeat);
      setBeanAttributes(req, aBoxSession, entry, repeat);

      sendFile(editJSP,req,resp);
      return;
    }

    if ( req.getParameter("SubmitView") != null && curEntryID != 0 )
    {
      setBeanAttributes(req, aBoxSession, curEntryID);
      sendFile(viewJSP,req,resp);
      return;
    }
    sendFile(listJSP,req,resp);
  }

  protected void saveToBean(int id, HttpServletRequest req, HttpServletResponse resp, BoxSession aBoxSession)
      	throws Exception
  {
	  BoxReservationEntry bean = null;
	  if ( id == 0 )
		  bean = home.add();
	  else
		  bean = home.get(new BaseIntKey(id));
		if ( bean == null )
		  return;

	  BoxReservationRepeatEntry repeat = new BoxReservationRepeatEntry();
    if (!getParameters(req, aBoxSession, bean, repeat))
    {
      setBeanAttributes(req, aBoxSession, bean, repeat);
  		req.setAttribute("ERROR_MSG", strErrMsg);
      sendFile(editJSP,req,resp);
      return;
    }

	  //should check the conflict there
	  if (home.update(bean, repeat, aBoxSession.getTimeZone()))
	  {
	    sendFile(listJSP,req,resp);
	    return;
	  }
    else
    {
      setBeanAttributes(req, aBoxSession, bean, repeat);
  		req.setAttribute("ERROR_MSG", "Time conflict!");
  		//Since the update will create the bean, and
  		//will not delete the bean if conflict, need to
  		//delete it here, and reset the id
  		//It is a new entry again
  		if (id == 0)
  		{
        home.remove(bean.getID());
  		  req.setAttribute("ID", "0");
  		}
      sendFile(editJSP,req,resp);
    }
  }

  protected boolean getParameters(HttpServletRequest req, BoxSession aBoxSession,
                              BoxReservationEntry bean,
                              BoxReservationRepeatEntry repeat)
  {
    if ( bean == null || repeat == null )
      return false;
    boolean result = true;

    bean.setUserID(aBoxSession.getLoginID());

	  String str = req.getParameter("SUBJECT");
	  if ( str != null && str.length()>0)
		  bean.setSubject(str);
	  else
		  bean.setSubject("No title");

	  str = req.getParameter("DESCRIPTION");
	  if ( str != null )
		  bean.setDescription(str);

	  str = req.getParameter("RESOURCEID");
	  if ( str != null )
	  {
		  int i = Integer.parseInt(str);
		  bean.setResourceID(i);
	  }
	  str = req.getParameter("ISALLDAY");
	  if ( str != null )
	  {
		  bean.setIsAllDay(Integer.parseInt(str) > 0);
	  }

	  Calendar tmpCal = Calendar.getInstance(aBoxSession.getTimeZone());
    Calendar tmpCal1 = Calendar.getInstance(aBoxSession.getTimeZone());
	  int tmpYear = tmpCal.get(Calendar.YEAR);
	  int tmpMonth = tmpCal.get(Calendar.MONTH);
	  int tmpDay = tmpCal.get(Calendar.DAY_OF_MONTH);
	  int tmpHour = tmpCal.get(Calendar.HOUR_OF_DAY);
	  int tmpMinute = tmpCal.get(Calendar.MINUTE);

	  str = req.getParameter("FROM_YEAR");
	  if ( str != null )
		  tmpYear = Integer.parseInt(str);
	  str = req.getParameter("FROM_MONTH");
	  if ( str != null )
		  tmpMonth = Integer.parseInt(str);
	  str = req.getParameter("FROM_DAY");
	  if ( str != null )
		  tmpDay = Integer.parseInt(str);
    if (bean.getIsAllDay())
    {
	    tmpCal.set(tmpYear, tmpMonth, tmpDay, 0, 0, 0);
	    tmpCal.set(Calendar.MILLISECOND, 0);
	    bean.setFromTime(new Timestamp(tmpCal.getTime().getTime()));
	    tmpCal.set(tmpYear, tmpMonth, tmpDay, 23, 59, 59);
	    tmpCal.set(Calendar.MILLISECOND, 999);
	    bean.setToTime(new Timestamp(tmpCal.getTime().getTime()));
    }
    else
    {
	    str = req.getParameter("FROM_HOUR");
	    if ( str != null )
		    tmpHour = Integer.parseInt(str);
	    str = req.getParameter("FROM_MINUTE");
	    if ( str != null )
		    tmpMinute = Integer.parseInt(str);
	    tmpCal.set(tmpYear, tmpMonth, tmpDay, tmpHour, tmpMinute, 0);
	    tmpCal.set(Calendar.MILLISECOND, 0);
	    bean.setFromTime(new Timestamp(tmpCal.getTime().getTime()));

	    str = req.getParameter("TO_HOUR");
	    if ( str != null )
		    tmpHour = Integer.parseInt(str);
	    str = req.getParameter("TO_MINUTE");
	    if ( str != null )
		    tmpMinute = Integer.parseInt(str);
	    tmpCal1.set(tmpYear, tmpMonth, tmpDay, tmpHour, tmpMinute, 0);
	    tmpCal1.set(Calendar.MILLISECOND, 0);
	    if ( tmpCal.after(tmpCal1))
	    {
	      result = false;
	      strErrMsg = "To time is greater than from time";
	    }
	    bean.setToTime(new Timestamp(tmpCal1.getTime().getTime()));
    }

	  str = req.getParameter("REPEAT_TYPE");
	  int tmp = 0;
	  if ( str != null )
		  tmp = Integer.parseInt(str);
	  if ( tmp == 0 )
	  {
		  bean.setRepeat(false);
		}
	  else
	  {
  		bean.setRepeat(true);
/*
  BY_WEEK = 1;
  BY_WEEK_OF_MONTH = 2;
  BY_MONTH = 3;
  BY_YEAR  = 4;
*/
		  repeat.setID(bean.getID());
		  repeat.setType(tmp);
		  switch (tmp)
		  {
		    case BoxReservationRepeatEntry.BY_WEEK:
  			  str = req.getParameter("REPEAT_EVERYWEEK");
		  	  if ( str != null )
				    repeat.setEvery(Integer.parseInt(str));
  			  else
		  		  repeat.setEvery(1);

  			  String days[] = req.getParameterValues("REPEAT_WEEKDAYS");
		  	  tmp = 0;
  			  for(int i=0; i<days.length; i++)
	  		  {
		  		  tmp |= Integer.parseInt(days[i]);
			    }
  			  repeat.setDayOfWeek(tmp);
		  	  break;
		    case BoxReservationRepeatEntry.BY_WEEK_OF_MONTH:
  			  str = req.getParameter("REPEAT_EVERYMONTH");
		  	  if ( str != null )
				    repeat.setEvery(Integer.parseInt(str));
  			  else
		  		  repeat.setEvery(1);

  			  str = req.getParameter("REPEAT_WHICHWEEKDAY");
		  	  if ( str != null)
				    repeat.setDayOfWeek(Integer.parseInt(str));

		  	  str = req.getParameter("REPEAT_WHICHWEEK");
			    if ( str != null )
				    repeat.setWhichDay(Integer.parseInt(str));
	  		  break;
		    case BoxReservationRepeatEntry.BY_MONTH:
		    case BoxReservationRepeatEntry.BY_YEAR:
			  break;
		  }

		  str = req.getParameter("UNTIL_YEAR");
	    if ( str != null )
		    tmpYear = Integer.parseInt(str);
	    str = req.getParameter("UNTIL_MONTH");
	    if ( str != null )
		    tmpMonth = Integer.parseInt(str);
	    str = req.getParameter("UNTIL_DAY");
	    if ( str != null )
		    tmpDay = Integer.parseInt(str);
  	  tmpCal1.set(tmpYear, tmpMonth, tmpDay, 24, 0, 0);
  	  tmpCal1.set(Calendar.MILLISECOND, 0);
	    if ( tmpCal.after(tmpCal1))
	    {
	      result = false;
	      strErrMsg = "Until time is greater than from time";
	    }
	    repeat.setUntilTime(new Timestamp(tmpCal1.getTime().getTime()));
	  }
	  return result;
  }

  protected void deleteBean(int id) throws Exception
  {
    if ( id != 0 )
    {
      home.remove(id, null);
    }
  }

  protected BoxReservationEntry setBeanAttributes(HttpServletRequest req, BoxSession aBoxSession, int ID)
  {
    BaseIntKey key = new BaseIntKey(ID);
    BoxReservationEntry entry = home.get(key);
    if (entry == null)
    {
      setDefaultAttributes(req, aBoxSession);
      return entry;
    }
    setBeanAttributes(req, aBoxSession, entry);
    return entry;
  }

  protected void setBeanAttributes(HttpServletRequest req, BoxSession aBoxSession, BoxReservationEntry entry)
  {
    BaseIntKey key = new BaseIntKey(entry.getID());
    BoxReservationRepeatEntry repeat = null;
 		if ( entry.getRepeat())
		{
			repeat = home.getRepeat(key);
    }
    setBeanAttributes(req, aBoxSession, entry, repeat);
  }

  protected void setBeanAttributes(HttpServletRequest req,
                                   BoxSession aBoxSession,
                                   BoxReservationEntry entry,
                                   BoxReservationRepeatEntry repeat)
  {
    //Set the defalut attributes for a new entry
    req.setAttribute("ID", Integer.toString(entry.getID()));
		req.setAttribute("SUBJECT", entry.getSubject());

    int tmp = entry.getResourceID();
    String str = req.getParameter("RESOURCEID");
    if ( str != null)
    {
      tmp = Integer.parseInt(str);
      if ( tmp != 0 )
        entry.setResourceID(tmp);
    }
    req.setAttribute("RESOURCEID", Integer.toString(tmp));
		req.setAttribute("ISALLDAY", (entry.getIsAllDay()?"1":"0"));

    Calendar tmpCal = Calendar.getInstance(aBoxSession.getTimeZone());
    tmpCal.setTime(entry.getFromTime());
		req.setAttribute("FROM_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)));
		req.setAttribute("FROM_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
		req.setAttribute("FROM_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
		req.setAttribute("FROM_HOUR", Integer.toString(tmpCal.get(Calendar.HOUR_OF_DAY)));
		req.setAttribute("FROM_MINUTE", Integer.toString(tmpCal.get(Calendar.MINUTE)));

    tmpCal.setTime(entry.getToTime());
		req.setAttribute("TO_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)));
		req.setAttribute("TO_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
		req.setAttribute("TO_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
		req.setAttribute("TO_HOUR", Integer.toString(tmpCal.get(Calendar.HOUR_OF_DAY)));
		req.setAttribute("TO_MINUTE", Integer.toString(tmpCal.get(Calendar.MINUTE)));

		req.setAttribute("DESCRIPTION", entry.getDescription());
		if ( entry.getRepeat())
		{
			req.setAttribute("REPEAT_TYPE", Integer.toString(repeat.getType()));
			req.setAttribute("REPEAT_EVERYWEEK", Integer.toString(repeat.getEvery()));
			req.setAttribute("REPEAT_WEEKDAYS", Integer.toString(repeat.getDayOfWeek()));
			req.setAttribute("REPEAT_WHICHWEEK", Integer.toString(repeat.getWhichDay()));
			req.setAttribute("REPEAT_WHICHWEEKDAY", Integer.toString(repeat.getDayOfWeek()));
			req.setAttribute("REPEAT_EVERYMONTH", Integer.toString(repeat.getEvery()));
			if ( repeat.getUntilTime() == null )
			{
				req.setAttribute("REPEAT_FOREVER", "0");
				req.setAttribute("UNTIL_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)+1));
				req.setAttribute("UNTIL_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
				req.setAttribute("UNTIL_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
			}
			else
			{
				tmpCal.setTime(repeat.getUntilTime());
				req.setAttribute("REPEAT_FOREVER", "0");
				req.setAttribute("UNTIL_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)));
				req.setAttribute("UNTIL_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
				req.setAttribute("UNTIL_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
			}
		}
		else
		{
			req.setAttribute("REPEAT_TYPE", "0");
			req.setAttribute("REPEAT_EVERYWEEK", "0");
			req.setAttribute("REPEAT_WEEKDAYS", "0");
			req.setAttribute("REPEAT_WHICHWEEK", "1");
			req.setAttribute("REPEAT_WHICHWEEKDAY", "1");
			req.setAttribute("REPEAT_EVERYMONTH", "1");

			req.setAttribute("REPEAT_FOREVER", "1");
			req.setAttribute("UNTIL_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)+1));
			req.setAttribute("UNTIL_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
			req.setAttribute("UNTIL_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
		}
  }

  protected void setDefaultAttributes(HttpServletRequest req, BoxSession aBoxSession)
  {
		//Set the defalut attributes for a new entry
		req.setAttribute("ID", "0");
		req.setAttribute("SUBJECT", "");
		req.setAttribute("ISALLDAY", "0");

		String str = (String) req.getParameter("RESOURCEID");
		if (str!= null)
    	req.setAttribute("RESOURCEID", str);
    else
      req.setAttribute("RESOURCEID", "1");

 		HttpSession session = req.getSession();
    Calendar tmpCal = (Calendar)session.getAttribute("currentDate");
    if (tmpCal==null)
      tmpCal = Calendar.getInstance(aBoxSession.getTimeZone());
		req.setAttribute("FROM_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)));
		req.setAttribute("FROM_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
		req.setAttribute("FROM_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
		req.setAttribute("FROM_HOUR", "8");
		req.setAttribute("FROM_MINUTE", "0");
		req.setAttribute("TO_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)));
		req.setAttribute("TO_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
		req.setAttribute("TO_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
		req.setAttribute("TO_HOUR", "9");
		req.setAttribute("TO_MINUTE", "0");

		req.setAttribute("DESCRIPTION", "");

		req.setAttribute("REPEAT_TYPE", "0");
		req.setAttribute("REPEAT_EVERYWEEK", "0");
		req.setAttribute("REPEAT_WEEKDAYS", "0");
		req.setAttribute("REPEAT_WHICHWEEK", "1");
		req.setAttribute("REPEAT_WHICHWEEKDAY", "1");
		req.setAttribute("REPEAT_EVERYMONTH", "1");

		req.setAttribute("REPEAT_FOREVER", "1");
		req.setAttribute("UNTIL_YEAR", Integer.toString(tmpCal.get(Calendar.YEAR)+1));
		req.setAttribute("UNTIL_MONTH", Integer.toString(tmpCal.get(Calendar.MONTH)));
		req.setAttribute("UNTIL_DAY", Integer.toString(tmpCal.get(Calendar.DAY_OF_MONTH)));
  }

	public void setViewJSP(String str)
	{
		viewJSP = str;
	}
	public void setEditJSP(String str)
	{
		editJSP = str;
	}
	public void setListJSP(String str)
	{
		listJSP = str;
	}
}
